home *** CD-ROM | disk | FTP | other *** search
- Procedure Vect_Diff(Var A,B,S :Vektor);
- begin
- S.X:=A.X-B.X;
- S.Y:=A.Y-B.Y;
- end;
-
- Procedure Vect_Sum(Var A,B,S :Vektor);
- begin
- S.X:=A.X+B.X;
- S.Y:=A.Y+B.Y;
- end;
-
- Procedure Vect_Scale(Var V:Vektor;M:Real);
- begin
- V.X:=V.X*M;
- V.Y:=V.Y*M;
- end;
-
- Procedure Vect_Ortho(A:Vektor;Var N :Vektor);
- begin
- N.X:=A.Y;
- N.Y:=-A.X;
- end;
-
- Function Bogenmass(Phi:Real):Real;
- begin
- Bogenmass:=Phi*Pi/180.0;
- end;
-
- Function Winkelmass(Phi:Real):Real;
- begin
- Winkelmass:=180.0*Phi/Pi;
- end;
-
- Function Winkel(X,Y:Real):Real; { gibt Bogenmass }
-
- Var Phi,
- Xabs,Yabs :Real;
-
- begin
- Xabs:=Abs(X);
- Yabs:=Abs(Y);
- If (Xabs<FastNull) and (Yabs<FastNull) then Phi:=0
- else If Xabs<FastNull then
- If Y>0 then Phi:=Pi_halbe else Phi:=-Pi_halbe
- else
- begin
- Phi:=ArcTan(Y/X);
- If X<0 then Phi:=Pi+Phi;
- end;
- If Phi<0 then Phi:=Phi+Pi_2;
- Winkel:=Phi;
- end;
-
- Procedure Normalize(Var Phi :Integer);
- begin
- Phi:=Phi mod 360;
- If Phi <0 Then Inc(Phi,360);
- end;
-
- Procedure Norm_CircPhi(Var Alpha,Beta :Integer);
- begin
- Normalize(Alpha);
- Normalize(Beta);
- If Beta<=Alpha Then Inc(Beta,360);
- end;
-
- Procedure Normalize_Real(Var Phi :Real);
- Var Rest :Real;
- begin
- Phi:=Frac(PHi/Pi_2)*Pi_2;
- If Phi <0 Then Phi:=Phi+Pi_2;
- end;
-
- Procedure Norm_CircPhi_Real(Var Alpha,Beta :Real);
- begin
- Normalize_Real(Alpha);
- Normalize_Real(Beta);
- If Beta-Alpha<=FastNull Then Beta:=Beta+Pi_2;
- end;
-
- Function DeltaPhi(Phi1,Phi2:Real):Real;
- begin
- Normalize_Real(Phi1);
- Normalize_Real(Phi2);
- Phi1:=Phi2-Phi1;
- Normalize_Real(Phi1);
- If Phi1>Pi then Phi1:=Phi1-Pi_2;
- DeltaPhi:=Phi1;
- end;
-
-
- Function InArc(Alpha,Beta,Phi :Real):Boolean;
- Const Eps=0.003;
- begin
- Normalize_Real(Phi);
- Norm_CircPhi_Real(alpha,beta);
- If (Beta>Pi_2) and (Phi<Alpha) Then Phi:=Phi+Pi_2;
- InArc:=(Phi>=Alpha-Eps) and (Phi<=Beta+Eps);
- end;
-
- Function CalcPhi(X,Y :Real):Integer;
- begin
- CalcPhi:=Round(Winkelmass(Winkel(X,Y)));
- end;
-
- Procedure Rotiere(Var X,Y:Real;Phi :Real); { Phi :Bogenmass}
- Var Si,Co,X1 :Real;
- begin
- X1:=X;
- Si:=Sin(Phi);Co:=Cos(Phi);
- X:=X*Co-Y*Si;
- Y:=X1*Si+Y*Co;
- end;
-
-
- Function Laenge(X,Y :Real):Real;
- begin
- Laenge:=Sqrt(Sqr(X)+Sqr(Y));
- end;
-
- Function Distanz(X1,Y1,X2,Y2 :Real):Real;
- begin
- Distanz:=Laenge(X2-X1,Y2-Y1);
- end;
-
- Function Distanz_VV(Var V1,V2 :Vektor):Real;
- begin
- Distanz_VV:=Distanz(V1.X,V1.Y,V2.X,V2.Y);
- end;
-
- Function Scalar_Prod(A,B :Vektor):Real;
- begin
- Scalar_Prod:=(A.X*B.X+A.Y*B.Y);
- end;
-
-
- Function Loese_QGl(A,B,C :Real;Var X1,X2 :Real):Integer;
- Var Diskriminante,D:Real;
- begin
- X1:=0;
- X2:=0;
- Loese_Qgl:=0;
- If Abs(A)>FastNull Then
- begin
- C:=C/A;
- B:=B/A;
- Diskriminante:=Sqr(B)-4.0*C;
- If Diskriminante>=0 Then
- begin
- D:=Sqrt(Diskriminante);
- Loese_Qgl:=2;
- If D<FastNull then Loese_QGL:=1;
- X1:=(D-B)/2.0;
- X2:=-(D+B)/2.0;
- end;
- end
- else
- If Abs(B)>Fastnull Then
- begin
- X1:=-C/B;
- X2:=X1;
- Loese_Qgl:=-1; {Linearer Fall};
- end;
- end;
-
- Procedure Tausche(Var X,Y :Real);
- Var T :Real;
- begin T:=X; X:=Y; Y:=T; end;
-
- Procedure Exchange(Var X,Y :Integer);
- Var T :Integer;
- begin T:=X; X:=Y; Y:=T; end;
-
-
- Function Loese_LinGL2(Var A,A1,B :Vektor;Var X :Vektor):Boolean;
- Var Pivot:Real;
- begin
- X.X:=0;X.Y:=0;
- Loese_LinGl2:=false;
- If Abs(A.X)<Fastnull Then
- begin
- Tausche(A.X,A.Y);
- Tausche(A1.X,A1.Y);
- Tausche(B.X,B.Y);
- end;
- If Abs(A.X)>Fastnull Then
- begin
- Pivot:=A.Y/A.X;
- A1.Y:=A1.Y-A1.X*Pivot;
- B.Y:=B.Y-B.X*Pivot;
- If Abs(A1.Y*A.X)>Fastnull Then
- begin
- Loese_LinGl2:=true;
- X.Y:=B.Y/A1.Y;
- X.X:=(B.X-A1.X*X.Y)/A.X
- end;
- end;
- end;
-
- Function HNF(Var G:Gerade):Boolean;
- Var L:Real;
- OK:Boolean;
- begin
- L:=Laenge(G.Richtung.X,G.Richtung.Y);
- OK:=L>FastNull;
- With G.Richtung Do
- If OK Then
- begin
- If (X*G.Ort.Y-Y*G.Ort.X)>0 Then L:=-L;
- begin
- X:=X/L;
- Y:=Y/L;
- end;
- end
- else
- begin X:=0;Y:=0; end;
- HNF:=OK;
- end;
-
-
- Function Make_Gerade(X1,Y1,X2,Y2:Real;Var G:Gerade):Boolean;
- begin
- G.Richtung.X:=X2-X1;
- G.Richtung.Y:=Y2-Y1;
- G.Ort.X:=X1;
- G.Ort.Y:=Y1;
- Make_Gerade:=HNF(G);
- end;
-
- Function Schnitt_GG(Var G1,G2 :Gerade; Var P :Vektor):Boolean;
- Var A,A1,B :Vektor;
- begin
- With G1 do
- begin
- A.X:=Richtung.Y;
- A1.X:=-Richtung.X;
- B.X:=Ort.X*Richtung.Y-Ort.Y*Richtung.X;
- end;
- With G2 do
- begin
- A.Y:=Richtung.Y;
- A1.Y:=-Richtung.X;
- B.Y:=Ort.X*Richtung.Y-Ort.Y*Richtung.X;
- end;
- Schnitt_GG:=Loese_LinGL2(A,A1,B,P);
- end;
-
- Function Abstand(G:Gerade;P:Vektor):Real;
- begin
- Abstand:=G.Richtung.Y*(P.X-G.Ort.X)-G.Richtung.X*(P.Y-G.Ort.Y);
- end;
-
- Function Winkel_halb(G1,G2 : Gerade;P:Vektor;Var G3 :Gerade):Boolean;
- Var OK:Boolean;
- SP :Vektor;
- Spitz:Boolean;
- DP1,DP2 :Real;
- begin
- OK:=Schnitt_GG(G1,G2,SP);
- If OK Then
- begin
- G3.Ort:=SP;
- DP1:=Abstand(G1,P);
- DP2:=Abstand(G2,P);
- Spitz:=DP1*DP2>0;
- With G3.Richtung Do
- begin
- Vect_Sum(G1.Richtung,G2.Richtung,G3.Richtung);
- If Spitz Then
- begin
- Tausche(X,Y);
- X:=-X;
- end;
- end;
- OK:=HNF(G3);
- end;
- Winkel_halb:=Ok;
- end;
-
- Function Lot(Var G1: Gerade;P:Vektor;Var PL :Vektor;Var GL :Gerade):Boolean;
- Var OK:Boolean;
- begin
- GL.Ort:=P;
- Vect_Ortho(G1.Richtung,Gl.Richtung);
- OK:=HNF(GL);
- If OK Then OK:=Schnitt_GG(G1,GL,PL) and ok;
- Lot:=OK;
- end;
-
- Function Parallele(Var G1:Gerade;Var P1:Vektor; Var GP :Gerade):Boolean;
- begin
- GP.Ort:=P1;
- GP.Richtung:=G1.Richtung;
- Parallele:=HNF(GP);
- end;
-
- Procedure KreisKoord(Rx,Ry,Phi :Real;Var Cx,Cy :Real);
- begin
- Cx:=Rx*Cos(Phi);
- Cy:=Ry*Sin(Phi);
- end;
-
- Function KreisPhi(Var X,Y :Real;Var K:Bogen):Real;
- begin
- KreisPhi:=Winkel(X*K.RadiusY,Y*K.RadiusX);
- end;
-
- Function GetKreisPhi(Var P:Vektor;Var K:Bogen):Real;
- begin
- Norm_KoordSys(P,K.Mitte,K.Theta);
- GetKreisPhi:=KreisPhi(P.X,P.Y,K);
- end;
-
-
- Procedure Norm_KoordSys(Var V, V0 :Vektor;Phi:Real);
- begin
- Vect_Diff(V,V0,V);
- Rotiere(V.X,V.Y,-Phi);
- end;
-
- Procedure Regen_KoordSys(Var V, V0 :Vektor;Phi:Real);
- begin
- Rotiere(V.X,V.Y,Phi);
- Vect_Sum(V,V0,V);
- end;
-
- Procedure Get_P_G(Var G1 :Gerade;Var P:Vektor;Sigma :Real);
- begin
- P:=G1.Richtung;
- Vect_Scale(P,Sigma);
- Vect_Sum(G1.Ort,P,P);
- end;
-
-
- Function Tangente(K1 :Bogen;P1 :Vektor;Var PB1,PB2 :Vektor):Integer;
- Var Kreis :Bogen;
- KreisPhi0,
- Cx,Cy :Real;
- InKreis :Boolean;
- Result,UV:Array[1..2] of Vektor;
- Nr,N,I :Integer;
- A,B,C,
- A2,B2,Bx,By,K,S :Real;
-
- Procedure GetResult(I :Integer);
- Var Phi :Real;
- XP :Vektor;
- Begin
- A:=B2*Sqr(UV[I].X)+A2*Sqr(UV[I].Y);
- B:=P1.X*UV[I].X*B2+P1.Y*UV[I].Y*A2;
- IF Abs(A) >FastNull Then
- begin
- S:=-B/A;
- Vect_Scale(UV[I],S);
- Vect_Sum(P1,UV[I],XP);
- Phi:=KreisPhi(XP.X,XP.Y,Kreis);
- If InArc(Kreis.alpha,Kreis.Beta,Phi) Then
- begin
- Inc(Nr,1);
- Result[Nr]:=XP;
- Regen_KoordSys(Result[Nr],K1.Mitte,K1.Theta);
- end;
- end;
- end;
-
- begin
- FillChar(Result,Sizeof(Result),0);
- Norm_KoordSys(P1,K1.Mitte,K1.Theta);
- { Kordinaten-Transformation in Null-Normal}
- { bezüglich Kreis}
- Kreis:=K1;
- Kreis.Theta:=0;
- Kreis.Mitte:=Nullpunkt;
- KreisPhi0:=KreisPhi(P1.X,P1.Y,Kreis);
- KreisKoord(Kreis.RadiusX,Kreis.RadiusY,KreisPhi0,Cx,Cy);
- InKreis:=(Laenge(Cx,Cy)-Laenge(P1.X,P1.Y))*0.1>FastNull;
- Nr:=0;
- If Not(Inkreis) Then
- begin
- A2:=Sqr(Kreis.RadiusX);B2:=Sqr(Kreis.RadiusY);
- K:=Sqr(P1.X)*B2+Sqr(P1.Y)*A2-A2*B2;
- BX:=2.0*P1.X*B2;
- BY:=2.0*P1.Y*A2;
- A:=Sqr(By)-4.0*A2*K;
- B:=2.0*Bx*By;
- C:=Sqr(Bx)-4.0*B2*K;
- For I:=1 to 2 Do
- begin
- UV[I].X:=1.0;
- UV[I].Y:=1.0;
- end;
- Nr:=Loese_Qgl(A,B,C,UV[1].Y,UV[2].Y);
- If Nr<1 then
- begin
- C:=Sqr(By)-4.0*A2*K;
- A:=Sqr(Bx)-4.0*B2*K;
- Nr:=Loese_Qgl(A,B,C,UV[1].X,UV[2].X);
- end;
- N:=Nr;
- Nr:=0;
- For I:=1 to N do Getresult(I);
- end; {If Inkreis }
- PB1:=Result[1];
- PB2:=Result[2];
- Tangente:=Nr;
- end;
-
- Function Polare(K1 :Bogen;P1 :Vektor;Var P2,P3 :Vektor; Var G :Gerade):Boolean;
- begin
- Polare:=false;
- If Tangente(K1,P1,P2,P3)=2 Then
- begin
- G.Ort:=P2;
- Vect_Diff(P3,P2,G.Richtung);
- Polare:=Hnf(G);
- end;
- end;
-
-
- Function Schnitt_KG(G1 :Gerade;K1:Bogen;Var P1,P2 :Vektor):Integer;
- Var Kreis:Bogen;
- A2,B2,A,B,C :Real;
- S :Array[1..2] of Real;
- Nr,I,N:Integer;
- Result,Ps: Array[1..2] of Vektor;
-
- Procedure GetResult(I :Integer);
- Var Phi :Real;
- Begin
- Phi:=KreisPhi(Ps[I].X,Ps[I].Y,Kreis);
- If InArc(Kreis.alpha,Kreis.Beta,Phi) Then
- begin
- Inc(Nr,1);
- Result[Nr]:=Ps[I];
- Regen_KoordSys(Result[Nr],K1.Mitte,K1.Theta);
- end;
- end;
-
- Begin
- FillChar(Result,Sizeof(Result),0);
- Norm_KoordSys(G1.Ort,K1.Mitte,K1.Theta);
- Rotiere(G1.Richtung.X,G1.Richtung.Y,-K1.Theta);
- { Kordinaten-Transformation in Null-Normal}
- { bezüglich Kreis}
- Kreis:=K1;
- Kreis.Theta:=0;
- Kreis.Mitte:=Nullpunkt;
- A2:=Sqr(Kreis.RadiusX);B2:=Sqr(Kreis.RadiusY);
- With G1.Ort do
- C:=Sqr(X)*B2+Sqr(Y)*A2-A2*B2;
- With G1 do
- B:=2.0*(Ort.X*Richtung.X*B2+Ort.Y*Richtung.Y*A2);
- With G1.Richtung Do
- A:=B2*Sqr(X)+A2*Sqr(Y);
- Nr:=Loese_QGL(A,B,C,S[1],S[2]);
- For I:=1 to Nr Do
- Get_P_G(G1,Ps[I],S[I]);
- N:=Nr;
- Nr:=0;
- For I:=1 to N do GetResult(I);
- P1:=Result[1];
- P2:=Result[2];
- Schnitt_KG:=Nr;
- end;
-
-
- Function Kreis_3P(P1,P2,P3 :Vektor;Var K:Bogen):Integer;
- Var Ms1,Ms2 :Gerade;
- V:Vektor;
- X:Vektor;
- Delta:Real;
- Ok:Boolean;
- begin
- With K Do
- begin
- Kreis_3P:=0;
- Ok := (Distanz_VV(P1,P2)>Fastnull) and
- (Distanz_VV(P1,P3)>Fastnull) and
- (Distanz_VV(P3,P2)>Fastnull);
- If Ok Then
- begin
- Vect_Sum(P1,P2,Ms1.Ort);
- Vect_Scale(Ms1.Ort,0.5);
- Vect_Sum(P2,P3,Ms2.Ort);
- Vect_Scale(Ms2.Ort,0.5);
- Vect_Diff(P2,P1,V);
- Vect_Ortho(V,Ms1.Richtung);
- Ok:=HNF(Ms1);
- If Ok Then
- begin
- Vect_Diff(P3,P2,V);
- Vect_Ortho(V,Ms2.Richtung);
- Ok:=HNF(Ms1);
- If OK Then
- begin
- Ok:=Schnitt_GG(Ms1,Ms2,Mitte);
- If OK Then
- Begin
- Theta:=0;
- RadiusX:=Distanz_VV(Mitte,P1);
- RadiusY:=RadiusX;
- Vect_Diff(P1,Mitte,X);
- Alpha:=Winkel(X.X,X.Y);
- Vect_Diff(P3,Mitte,X);
- Beta:=Winkel(X.X,X.Y);
- Vect_Diff(P2,Mitte,X);
- Delta:=Winkel(X.X,X.Y);
- Normalize_Real(Alpha);
- Normalize_Real(Beta);
- Normalize_Real(Delta);
- If Not(InArc(Alpha,Beta,Delta)) Then Tausche(Alpha,Beta);
- Kreis_3P:=1;
- End else Kreis_3P:=2; { Gerade P1,P3 }
- end;
- end;
- end;
- end;
- end;
-
- Function Kreis_SEC(P1,P2 :Vektor;Var K:Bogen):Boolean;
- Var V :Vektor;
- Phi:Real;
- begin
- Kreis_Sec:=false;
- V:=P1;
- Norm_KoordSys(V,K.Mitte,K.Theta);
- If Laenge(V.X,V.Y)>FastNull Then
- begin
- Phi:=KreisPhi(V.X,V.Y,K);
- KreisKoord(K.RadiusX,K.RadiusY,Phi,P2.X,P2.Y);
- Regen_KoordSys(P2,K.Mitte,K.Theta);
- Kreis_Sec:=true;
- End;
- end;
-
- Procedure Koord_to_Vekt(Var K:Koord;Var V:Vektor);
- begin
- V.X:=K.X;
- V.Y:=K.Y;
- end;
-
- Procedure Vekt_to_Koord(Var V:Vektor;Var K:Koord);
- begin
- K.X:=RealtoInt(V.X);
- K.Y:=RealtoInt(V.Y);
- end;
-
- Function Linie_OK(Var O :Bildelement):Boolean;
- begin
- Linie_OK:=(O.ElementTyp in [Linie,M_line]) and
- ((O.Aufhaenger.X<>O.Endpunkt.X) or (O.Aufhaenger.Y<>O.Endpunkt.Y));
- end;
-
- Function Circle_OK(Var O :Bildelement):Boolean;
- begin
- With O Do
- Circle_OK:=(ElementTyp in [Kreis,M_arc]) and
- (HalbX>0) and (HalbY>0) and (Segmentalpha<>SegmentBeta);
- end;
-
- Function GetObj_Kreis(Var K:Bogen; Var O:Bildelement):Boolean;
- begin
- Fillchar(O,SizeOf(O),0);
- With O,K do
- begin
- ElementTyp:=Kreis;
- HalbX:=RealtoInt(RadiusX);
- HalbY:=RealtoInt(RadiusY);
- SegmentAlpha:=RealtoInt(Winkelmass(Alpha));
- Segmentbeta:=RealtoInt(Winkelmass(Beta));
- Orient:=RealtoInt(Winkelmass(Theta));
- Vekt_to_Koord(Mitte,Aufhaenger);
- GetObj_Kreis:=Circle_OK(O);
- end;
- end;
-
- Function GetKreis_Obj( Var O:Bildelement;Var K:Bogen):Boolean;
- begin
- GetKreis_Obj:=false;
- Fillchar(K,SizeOf(K),0);
- If (O.ElementTyp in [Kreis,M_arc]) then
- With O,K do
- begin
- GetKreis_Obj:=True;
- RadiusX:=HalbX;
- RadiusY:=HalbY;
- Alpha:=Bogenmass(Segmentalpha);
- Beta:=Bogenmass(Segmentbeta);
- Theta:=Bogenmass(Orient);
- Koord_to_Vekt(Aufhaenger,Mitte);
- end;
- end;
-
-
-
- Function GetObj_Gerade(Var P1,P2:Vektor; Var O:Bildelement):Boolean;
- begin
- Fillchar(O,SizeOf(O),0);
- With O do
- begin
- ElementTyp:=Linie;
- Vekt_to_Koord(P1,Aufhaenger);
- Vekt_to_Koord(P2,Endpunkt);
- GetObj_Gerade:=Linie_OK(O);
- end;
- end;
-
-
- Function GetGerade_Obj( Var O:Bildelement;Var G:Gerade):Boolean;
- begin
- GetGerade_Obj:=False;
- If (O.ElementTyp in [Linie,M_Line]) then
- With O Do
- GetGerade_Obj:=Make_Gerade(Aufhaenger.X,Aufhaenger.Y,
- EndPunkt.X,EndPunkt.Y,G);
- end;
-
-
- Procedure Mirror(Var Px,Py :integer; Spiegel :Spiegelpar);
- Var P1,P2 :Real;
- begin
- P1:=Px;
- P2:=Py;
- With Spiegel Do
- begin
- Px:=RealtoInt(A11*P1+A12*P2+Ex);
- Py:=RealtoInt(A21*P1+A22*P2+Ey);
- end;
- end;
-
- Procedure GetSpiegel(Ax,Ay,Bx,By :Integer;Lot,TextMirr:Boolean;
- Var Spiegel :Spiegelpar);
- Var DeltaX,DeltaY,N,
- DXY,DX2,DY2,L :Real;
- begin
- If Lot then L:=1.0
- else L:=2.0;
- DeltaX:=Bx-Ax;
- DeltaY:=By-Ay;
- DXY:=DeltaX*DeltaY;
- DX2:=Sqr(DeltaX);
- DY2:=Sqr(DeltaY);
- N:=DX2+DY2;
- With Spiegel Do
- begin
- If DeltaX<0 then DeltaY:=-DeltaY;
- Phiaxis:=CalcPhi(Abs(DeltaX),DeltaY);
- A11:=1.0-L*DY2/N;
- A12:=L*DXY/N;
- A21:=A12;
- A22:=1.0-L*DX2/N;
- Ex:=L*(DY2*Ax-DXY*Ay)/N;
- Ey:=L*(DX2*Ay-DXY*Ax)/N;
- Mirrtext:=TextMirr;
- end;
- end;
-
- Function ConvertRect(Var O:Bildelement;
- Var P1,P2,P3,P4 :Vektor;
- Var G1,G2,G3,G4 :Gerade):Boolean;
- Var Theta,lb :Real;
- P0 :vektor;
- begin
- With O do
- begin
- Lb:=0.5*Rand+Fastnull;
- Koord_to_Vekt(Aufhaenger,P0);
- P1.X:=Lb; P1.Y:=LB;
- P2.X:=Rlaenge-LB; P2.Y:=LB;
- P3.X:=P2.X; P3.y:=Rbreite-LB;
- P4.X:=LB; P4.y:=P3.y;
- Theta:=Bogenmass(Orient);
- Rotiere(P1.X,P1.Y,Theta);
- Rotiere(P2.X,P2.Y,Theta);
- Rotiere(P3.X,P3.Y,Theta);
- Rotiere(P4.X,P4.Y,Theta);
- Vect_Sum(P0,P1,P1);
- Vect_Sum(P0,P2,P2);
- Vect_Sum(P0,P3,P3);
- Vect_Sum(P0,P4,P4);
- G1.Ort:=P1;G2.Ort:=P2;G3.Ort:=P3;G4.Ort:=P4;
- Vect_Diff(P2,P1,G1.Richtung);
- Vect_Ortho(G1.Richtung,G2.Richtung);
- G3.Richtung:=G1.Richtung;G4.Richtung:=G2.Richtung;
- ConvertRect:=Hnf(G1) and HNF(G2) and HNF(G3) and HNF(G4);
- end;
- end;
-